<template>
  <div class="upload-container upload-custom-container">
    <div>
      <draggable v-if="isImg" v-model="fileList" @end="dragEnd">
        <div v-for="(item, i) in fileList" :key="i" class="card animated fadeInDown">
          <div v-if="item.url" class="img-wrapper">
            <img :src="item.url">
          </div>
          <div class="ctrl-wrapper">
            <a-icon @click="previewImage(item, i)" type="eye"/>
            <a-icon @click="remove(item, i)" type="delete"/>
          </div>
        </div>
      </draggable>
      <div
        @click="showUpload"
        v-if="fileList.length < limit"
        class="card"
        :class="isImg ? 'add-card' : 'add-not-card'"
      >
        <a-icon type="plus"/>
        <input
          :multiple="limit > 1"
          @change="upload"
          :accept="accept"
          type="file"
          v-show="false"
          ref="input"
        >
      </div>
      <section v-if="!isImg">
        <div v-for="(item, i) in fileList" :key="i" class="uploaded-item center-flex">
          <span
            @click="previewVideo(item.url)"
            class="url-detail text-ellipsis"
          >{{item.path || item.url}}</span>
          <a-icon @click="remove(item, i)" type="delete"/>
        </div>
      </section>
    </div>
    <p v-if="tip" class="tip">{{tip}}</p>
  </div>
</template>

<script>
import axios from 'axios'
import draggable from 'vuedraggable'

import { aliToken } from '@/api/uploadToken'
import uploader from 'kuan-utils/lib/uploader'

export default {
  props: {
    value: {
      type: Array
    },
    tip: {
      type: String,
      default: ''
    },
    limit: {
      type: Number,
      default: 1
    },
    size: {
      type: Number,
      default: 60000
    },
    accept: {
      type: String,
      default: 'image/png, image/jpeg, image/gif'
    },
    module: {
      type: String,
      default: ''
    },
    validate: {
      type: Function
    },
  },
  computed: {
    isImg() {
      return this.accept === 'image/png, image/jpeg, image/gif'
    }
  },
  data() {
    return {
      visible: false,
      fileList: this.value || [],
      formData: {
        'x:module': this.module
      },
      action: 'https://dashboard-static.oss-cn-hangzhou.aliyuncs.com',
      activeItem: {}
    }
  },
  watch: {
    value(e) {
      this.fileList = e
    }
  },
  methods: {
    async getName(file) {
      const { name } = file
      const md5Name = await uploader.getFileMD5(file)
      const suffix = name.substr(name.lastIndexOf('.'))
      return md5Name + suffix
    },
    async beforeUpload(file) {
      if (file.size / 1000 > this.size) {
        const message = '图片过大'
        this.$message.warning(message)
        return Promise.reject(message)
      }
      if (this.validate) {
        await this.validate(file)
      }
      const name = await this.getName(file)
      const { accessid, callback, dir, policy, signature, host } = await aliToken()
      this.formData['key'] = `${dir}${name}`
      this.action = host
      this.formData['OSSAccessKeyId'] = accessid
      this.formData['policy'] = policy
      this.formData['Signature'] = signature
      this.formData['callback'] = callback
      return true
    },
    async showUpload() {
      const { input } = this.$refs
      input.click()
    },
    async uploadItem(file) {
      await this.beforeUpload(file)
      const fd = new FormData()

      Object.entries(this.formData).forEach(([key, value]) => {
        fd.append(key, value)
      })
      fd.append('file', file)
      const { data } = await axios({
        url: this.action,
        method: 'post',
        data: fd
      })
      // const {domain, file_id, file_path} = data
      const { base_url, path, id, width, height } = data
      const item = {
        url: this.isImg ? `${base_url}${path}-300x300` : `${base_url}${path}`,
        id: id,
        width: width,
        height: height,
        path: path
      }
      this.fileList.push(item)
      this.$emit('success', item)
      this.change()
    },
    upload() {
      const { files = [] } = this.$refs.input
      try {
        for (let i = 0; i < files.length; i++) {
          this.uploadItem(files[i])
        }
      } catch (e) {
        this.$message.warning(e.message)
      }
    },
    change() {
      const value = this.fileList
      this.$emit('change', value)
      // this.$emit('input', value)
    },
    previewImage(item) {
      this.$preview(item.url)
    },
    previewVideo(url) {
      window.open(url)
    },
    remove(item, i) {
      this.fileList = this.fileList.filter((it, index) => index !== i)
      this.change()
      this.$emit('remove', item)
    },
    dragEnd() {
      this.change()
      this.$emit('sort', this.fileList)
    }
  },
  components: {
    draggable
  }
}
</script>

<style lang="scss" scoped>
.upload-container {
  display: inline-block;
}

.card {
  overflow: hidden;
  border-radius: 6px;
  box-sizing: border-box;
  width: 120px;
  height: 120px;
  margin: 0 8px 8px 0;
  display: inline-block;
  border: 1px solid #c0ccda;
  line-height: 120px;
  vertical-align: top;
  text-align: center;
  position: relative;
  &:hover {
    .ctrl-wrapper {
      cursor: pointer;
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      display: block;
    }
  }
  &.add-card {
    cursor: pointer;
    border: 1px dashed #c0ccda;
    background-color: #fbfdff;
    font-size: 28px;
    color: #8c939d;
    &:hover {
      border-color: #409eff;
      color: #409eff;
    }
  }
  &.add-not-card {
    border: 1px dashed #c0ccda;
    background-color: #fbfdff;
    font-size: 20px;
    color: #8c939d;
    width: 50px;
    height: 50px;
    .el-icon-plus {
      display: flex;
      justify-content: center;
      margin-top: 14px;
    }
  }
  .img-wrapper {
    width: 100%;
    height: 100%;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    img {
      width: 100%;
    }
  }
}

.ctrl-wrapper {
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  color: white;
  font-size: 20px;
  display: none;
  i {
    padding: 0 8px;
  }
}
.url-detail {
  display: inline-block;
  max-width: 300px;
  overflow: hidden;
}
.uploaded-item {
  cursor: pointer;
  i {
    padding: 0 10px;
  }
}
.tip {
  color: gray;
  padding: 0;
  margin: 0;
}
</style>

<style>
.upload-custom-container > div {
  display: inline-block;
}
</style>
